


// 负责把data选项中的属性转换成响应式数据
// data中的某个属性也是对象，把该属性转换成响应式数据
// 数据变化发送通知
/***注意两个步骤 */
// 1.如果val是对象，把该对象中的属性也变成getter/setter
// 2.把新赋值的对象内部属性转成响应式数据        
class Observer{
  constructor(data){
    this.walk(data)//$data
  }
  walk(data){
  //遍历对象的所有属性
  // 判断data是否是对象
    if(!data || typeof data !== 'object'){ return }
    Object.keys(data).forEach(key => {//
      this.defineReactive(data, key, data[key])
    })
  }
  
  defineReactive(obj, key, val){
    let that = this//Observer实例
    let dep = new Dep()//负责收集依赖 发送通知
    this.walk(val)  //  1.如果val是对象，把该对象中的属性也变成getter/setter
    // 调用Object.defineProperty方法将我们的属性转换成getter和setter
    Object.defineProperty(obj, key, {
      enumerable: true,
      configurable: true,
      get(){//在getter中收集依赖
        Dep.target && dep.addSub(Dep.target)//收集依赖
        return val//不能写obj[key],会再次触发get方法，会死递归
      },
      set(newValue){//在setter中通知依赖
        //此处内this指向data对象
        if(newValue === val){ return }
        val = newValue
        that.walk(newValue)  //2.把新赋值的对象内部属性转成响应式数据        
        // 发送通知
        dep.notify()
      }
    })
  }
}